home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianComplexControls.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
19KB
|
739 lines
/* ScianComplexControls.c: John R Murray August 23, 1990
Repository for all those weird controls with lots of little
thingamabobs that you can move around */
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianColors.h"
#include "ScianIDs.h"
#include "ScianErrors.h"
#include "ScianEvents.h"
#include "ScianControls.h"
#include "ScianButtons.h"
#include "ScianComplexControls.h"
#include "ScianMethods.h"
#include "ScianArrays.h"
#include "ScianWindows.h"
#include "ScianObjWindows.h"
#include "ScianScripts.h"
#include "ScianDialogs.h"
#include "ScianFontSystem.h"
#include "ScianStyle.h"
#include "ScianDraw.h"
#include "ScianTextBoxes.h"
#include "ScianSnap.h"
/* globals */
ObjPtr boundsControlClass; /* Class of bounds control */
ObjPtr XYControlClass; /* Class of XY controls */
#define LINELENGTH 15.0 /* length of border lines */
#define BOUNDSBORDER 8.0 /* blank border around control stuff */
#define LABELFONTFUDGE 1 /* fudge strings up (or <0 = down) to center */
ObjPtr NewBoundsControl(left, right, bottom, top, label)
int left, right, bottom, top;
char *label;
/*Makes a new panel with bounds left, right, bottom, top, and label label*/
{
real values[6], hilites[6];
ObjPtr valuesArray, hilitesArray;
ObjPtr retVal;
ObjPtr labelPtr;
ObjPtr hilightPtr;
values[0] = 0.0;
values[1] = 1.0;
values[2] = 0.0;
values[3] = 1.0;
values[4] = 0.0;
values[5] = 1.0;
hilites[0] = false;
hilites[1] = false;
hilites[2] = false;
hilites[3] = false;
hilites[4] = false;
hilites[5] = false;
valuesArray = NewRealArray(1, (long) 6);
hilitesArray = NewRealArray(1, (long) 6);
if (valuesArray && hilitesArray)
{
CArray2Array(valuesArray, values);
CArray2Array(hilitesArray, hilites);
retVal = NewObject(boundsControlClass, 0);
Set2DIntBounds(retVal, left, right, bottom, top);
SetVar(retVal, VALUE, (ThingPtr) valuesArray);
SetVar(retVal, HIGHLIGHTED, (ThingPtr) hilitesArray);
labelPtr = NewString(label);
SetVar(retVal, NAME, labelPtr);
return retVal;
}
else
{
return NULLOBJ;
}
}
void SetBoundsControl(obj)
ObjPtr obj;
{
if (logging) LogControl(obj);
}
/* Methods functions for Bounds Controls */
myMin(a,b)
int a,b;
{
return a < b ? a : b;
}
int DrawBoundsControl(theControl)
ObjPtr theControl;
{
#ifdef GRAPHICS
int left, right, bottom, top;
ObjPtr theLabel;
char *label;
ObjPtr valuesArray, hilitesArray;
real values[6], hilites[4];
real xmin, xmax, ymin, ymax, zmin, zmax;
Coord v[4][2];
real xPos, yPos;
real xRel, yRel;
real fudgeScale;
real recsize, recwidth, recdepth;
/* get bounds, and draw control background */
if (!Get2DIntBounds(theControl, &left, &right, &bottom, &top))
{
return false;
}
if (IsDrawingRestricted(left, right, bottom, top))
{
return false;
}
valuesArray = GetFixedArrayVar("DrawBoundsControl",theControl,VALUE,1,6L);
hilitesArray = GetFixedArrayVar("DrawBoundsControl", theControl,
HIGHLIGHTED, 1, 4L);
if (valuesArray && hilitesArray)
{
Array2CArray(values, valuesArray);
xmin = values[0];
xmax = values[1];
ymin = values[2];
ymax = values[3];
zmin = values[2];
zmax = values[3];
Array2CArray(hilites, hilitesArray);
}
else
{
/* figure out a recovery? */
ReportError("DrawBoundsControl", "control missing bounds or values!\n");
return;
}
DrawRaisedRect(left, right, bottom, top, UIBACKGROUND);
/* attempt to draw the control label */
theLabel = GetStringVar("DrawBoundsControl", theControl, NAME);
if (theLabel)
{
label = GetString(theLabel);
SetUIColor(UITEXT);
SetUIFont(BUTTONFONT);
DrawAString(CENTERALIGN, (left + right) / 2,
(top+bottom)/2 + LABELFONTFUDGE - (int)BUTTONFONTSIZE/2,
label);
}
SetUIColor(UITEXT);
/* Draw the rest of the parts of the control */
recsize = myMin(right - left, top - bottom) - 2*(BOUNDSBORDER + LINELENGTH + 3);
recwidth = (int) ((2*recsize) / 3);
recdepth = (int) (recsize - recwidth);
/* Draw icon-like central figure, in center of control */
move2((int) ((right - left) / 2),(int) ((top - bottom) / 2));
rmv2((int) (recdepth / 2.0), (int) (recdepth / 2.0));
rdr2(-recwidth, 0.0);
rdr2(0.0, -recwidth);
rdr2(recwidth, 0.0);
rdr2(0.0, recwidth);
rdr2(recdepth, recdepth);
rdr2(-recwidth, 0.0);
rdr2(0.0, -recwidth);
rdr2(recwidth, 0.0);
rdr2(0.0, recwidth);
rmv2(-recwidth, 0.0);
rdr2(-recdepth, -recdepth);
rmv2(0.0, -recwidth);
rdr2(recdepth, recdepth);
rmv2(recwidth, 0.0);
rdr2(-recdepth, -recdepth);
/* Draw bounds range lines. */
#endif /* GRAPHICS */
}
int PressBoundsControl(theControl, mouseX, mouseY, whichButton)
ObjPtr theControl;
int mouseX, mouseY;
int whichButton;
{
#ifdef INTERACTIVE
if (logging) LogControl(theControl);
#endif /* INTERACTIVE */
}
#define INITMINX 0.0
#define INITMAXX 1.0
#define INITX 0.5
#define INITMINY 0.0
#define INITMAXY 1.0
#define INITY 0.5
ObjPtr NewXYControl(left, right, bottom, top, name)
int left, right, bottom, top;
char *name;
{
real values[2], range[4];
ObjPtr valuesArray, rangeArray;
ObjPtr retVal;
values[0] = INITX;
values[1] = INITY;
range[0] = INITMINX;
range[1] = INITMAXX;
range[2] = INITMINY;
range[3] = INITMAXY;
valuesArray = NewRealArray(1, 2L);
rangeArray = NewRealArray(1, 4L);
if (valuesArray && rangeArray)
{
CArray2Array(valuesArray, values);
CArray2Array(rangeArray, range);
retVal = NewObject(XYControlClass, 0);
Set2DIntBounds(retVal, left, right, bottom, top);
SetVar(retVal, VALUE, valuesArray);
SetVar(retVal, RANGE, rangeArray);
SetVar(retVal, HIGHLIGHTED, NewInt(false));
SetVar(retVal, BACKGROUND, NewInt(UIPGREEN));
SetVar(retVal, NAME, NewString(name));
return retVal;
}
else
{
OMErr();
return NULLOBJ;
}
}
#define XYCONTROLMARGIN (EDGE + 2)
#define XYCONTROLKNOBSIZE 7
#define XYCONTROLSLOP (SLOP + XYCONTROLMARGIN + XYCONTROLKNOBSIZE)
ObjPtr DrawXYControl(theControl)
ObjPtr theControl;
{
#ifdef GRAPHICS
int left, right, bottom, top;
ObjPtr theLabel;
char *label;
ObjPtr valuesArray, rangeArray, hilitesArray;
real value[2], range[4];
real xPos, yPos;
real xRel, yRel;
real fudgeScale;
real recsize, recwidth, recdepth;
/* get bounds, and draw control background */
if (!Get2DIntBounds(theControl, &left, &right, &bottom, &top))
{
return NULLOBJ;
}
if (IsDrawingRestricted(left, right, bottom, top))
{
return ObjFalse;
}
valuesArray = GetFixedArrayVar("DrawXYControl", theControl, VALUE, 1, 2L);
rangeArray = GetFixedArrayVar("DrawXYControl", theControl, RANGE, 1, 4L);
if (valuesArray && rangeArray)
{
Array2CArray(value, valuesArray);
Array2CArray(range, rangeArray);
}
else
{
/* figure out a recovery? */
ReportError("DrawXYControl", "control missing values");
return NULLOBJ;
}
/* draw the field */
DrawField(theControl);
DrawSunkenRect(left, right, bottom, top, UIPGREEN);
left = left + XYCONTROLMARGIN + XYCONTROLKNOBSIZE;
right = right - XYCONTROLMARGIN - XYCONTROLKNOBSIZE;
bottom = bottom + XYCONTROLMARGIN + XYCONTROLKNOBSIZE;
top = top - XYCONTROLMARGIN - XYCONTROLKNOBSIZE;
xPos = left + (right - left) * (value[0]-range[0])/(range[1]-range[0]);
yPos = bottom + (top - bottom) * (value[1]-range[2])/(range[3]-range[2]);
/* draw the thingamabob in the middle, for now */
DrawRaisedRect(xPos - XYCONTROLKNOBSIZE, xPos + XYCONTROLKNOBSIZE,
yPos - XYCONTROLKNOBSIZE, yPos + XYCONTROLKNOBSIZE,
GetPredicate(theControl, HIGHLIGHTED) ? UIHIBACKGROUND : UIBACKGROUND);
#endif /* GRAPHICS */
}
ObjPtr PressXYControl(object, mouseX, mouseY, flags)
ObjPtr object;
int mouseX, mouseY;
long flags;
/*Track a click in an XY control. Double-click snaps to corner, edge, or center*/
{
#ifdef INTERACTIVE
real left, right, bottom, top;
int li, ri, bi, ti;
ObjPtr valueArray, rangeArray;
real value[2], range[4];
real oldv0, oldv1; /* old values of value[0] and [1] */
int lastX, lastY; /*Last X and Y mouse position*/
Bool dontTrack, alwaysChange; /*True iff don't track, always change*/
if ( ! Get2DIntBounds(object, &li, &ri, &bi, &ti))
{
#if 0
I think Eric changed this in Austin
GetWindowBounds(&li, &ri, &bi, &ti);
#else
return ObjFalse;
#endif
}
left = li;
right = ri;
bottom = bi;
top = ti;
if (mouseX < left || mouseX > right || mouseY < bottom || mouseY > top)
{
return ObjFalse;
}
if (TOOL(flags) == T_HELP)
{
ContextHelp(object);
return ObjTrue;
}
/* it's really a press, and not a helpclick, so.. */
SaveForUndo(object);
left = left + XYCONTROLMARGIN + XYCONTROLKNOBSIZE;
right = right - XYCONTROLMARGIN - XYCONTROLKNOBSIZE;
bottom = bottom + XYCONTROLMARGIN + XYCONTROLKNOBSIZE;
top = top - XYCONTROLMARGIN - XYCONTROLKNOBSIZE;
/*Get the current value of the control*/
valueArray = GetFixedArrayVar("PressXYControl", object, VALUE, 1, 2L);
rangeArray = GetFixedArrayVar("PressXYControl", object, RANGE, 1, 4L);
if (!valueArray || !rangeArray)
{
return ObjFalse;
}
Array2CArray(value, valueArray);
Array2CArray(range, rangeArray);
oldv0 = value[0];
oldv1 = value[1];
lastX = value[0];
lastY = value[1];
if (flags & F_DOUBLECLICK)
{
FuncTyp method;
/*Snap current value to closest corner, side, or center*/
if ((mouseX - left) / (right - left) < 0.25)
{
value[0] = range[0];
}
else if ((mouseX - left) / (right - left) > 0.75)
{
value[0] = range[1];
}
else
{
value[0] = (range[1] + range[0]) / 2;
}
if ((mouseY - bottom) / (top - bottom) < 0.25)
{
value[1] = range[2];
}
else if ((mouseY - bottom) / (top - bottom) > 0.75)
{
value[1] = range[3];
}
else
{
value[1] = (range[3] + range[2]) / 2;
}
valueArray = NewRealArray(1, 2L);
CArray2Array(valueArray, value);
SetVar(object, VALUE, valueArray);
DrawMe(object);
ChangedValue(object);
return ObjTrue;
}
dontTrack = GetPredicate(object, TRACKNOT);
alwaysChange = GetPredicate(object, ALWAYSCHANGE);
SetVar(object, HIGHLIGHTED, NewInt(true));
if (flags & F_SHIFTDOWN)
{
lastX = mouseX;
lastY = mouseY;
SetVar(object, HIGHLIGHTED, NewInt(true));
DrawMe(object);
while (abs(lastX - mouseX) < 3 && abs(lastY - mouseY) < 3)
{
if (!Mouse(&mouseX, &mouseY))
return ObjTrue;
if (alwaysChange && !dontTrack)
{
ChangedValue(object);
}
}
if (abs(lastX - mouseX) > abs(lastY - mouseY)) /* X axis only */
{
while (Mouse(&mouseX, &mouseY))
{
if (mouseX != lastX)
{
lastX = mouseX;
if (mouseX < left - XYCONTROLSLOP
|| mouseX > right + XYCONTROLSLOP
|| mouseY < bottom - XYCONTROLSLOP
|| mouseY > top + XYCONTROLSLOP)
{
/* outside slop rectangle, restore old values */
value[0] = oldv0;
value[1] = oldv1;
SetVar(object, HIGHLIGHTED, NewInt(false));
}
else /* calculate new values based on mouse position */
{
value[0] = range[0] + ((mouseX - left) / (right - left)) * (range[1] - range[0]);
if (value[0] < range[0]) value[0] = range[0];
if (value[0] > range[1]) value[0] = range[1];
SetVar(object, HIGHLIGHTED, NewInt(true));
}
valueArray = NewRealArray(1, 2L);
CArray2Array(valueArray, value);
SetVar(object, VALUE, valueArray);
DrawMe(object);
if (!dontTrack)
{
ChangedValue(object);
}
}
else if (alwaysChange && !dontTrack)
{
ChangedValue(object);
}
}
}
else /* Y axis only */
{
while (Mouse(&mouseX, &mouseY))
{
if (mouseY != lastY)
{
lastY = mouseY;
if (mouseX < left - XYCONTROLSLOP
|| mouseX > right + XYCONTROLSLOP
|| mouseY < bottom - XYCONTROLSLOP
|| mouseY > top + XYCONTROLSLOP)
{
/* outside slop rectangle, restore old values */
value[0] = oldv0;
value[1] = oldv1;
SetVar(object, HIGHLIGHTED, NewInt(false));
}
else /* calculate new values based on mouse position */
{
value[1] = range[2] + ((mouseY - bottom) / (top - bottom)) * (range[3] - range[2]);
if (value[1] < range[2]) value[1] = range[2];
if (value[1] > range[3]) value[1] = range[3];
SetVar(object, HIGHLIGHTED, NewInt(true));
}
valueArray = NewRealArray(1, 2L);
CArray2Array(valueArray, value);
SetVar(object, VALUE, valueArray);
DrawMe(object);
if (!dontTrack)
{
ChangedValue(object);
}
}
else if (alwaysChange && !dontTrack)
{
ChangedValue(object);
}
}
}
}
else /* free tracking on X and Y axes */
{
while (Mouse(&mouseX, &mouseY))
{
if (mouseX != lastX || mouseY != lastY)
{
lastX = mouseX;
lastY = mouseY;
if (mouseX < left - XYCONTROLSLOP
|| mouseX > right + XYCONTROLSLOP
|| mouseY < bottom - XYCONTROLSLOP
|| mouseY > top + XYCONTROLSLOP)
{
/* outside slop rectangle, restore old values */
value[0] = oldv0;
value[1] = oldv1;
SetVar(object, HIGHLIGHTED, NewInt(false));
}
else /* calculate new values based on mouse position */
{
value[0] = range[0] + ((mouseX - left) / (right - left)) * (range[1] - range[0]);
if (value[0] < range[0]) value[0] = range[0];
if (value[0] > range[1]) value[0] = range[1];
value[1] = range[2] + ((mouseY - bottom) / (top - bottom)) * (range[3] - range[2]);
if (value[1] < range[2]) value[1] = range[2];
if (value[1] > range[3]) value[1] = range[3];
SetVar(object, HIGHLIGHTED, NewInt(true));
}
valueArray = NewRealArray(1, 2L);
CArray2Array(valueArray, value);
SetVar(object, VALUE, valueArray);
DrawMe(object);
if (!dontTrack)
{
ChangedValue(object);
}
}
else if (alwaysChange && !dontTrack)
{
DrawMe(object);
ChangedValue(object);
}
}
}
if (dontTrack)
{
ChangedValue(object);
}
SetVar(object, HIGHLIGHTED, NewInt(false));
ImInvalid(object);
if (logging) LogControl(object);
return ObjTrue;
#endif /* INTERACTIVE */
}
#ifdef PROTO
Bool SetXYControlLimits(ObjPtr theControl, real minX, real maxX,
real minY, real maxY)
#else
Bool SetXYControlLimits(theControl, minX, maxX, minY, maxY)
ObjPtr theControl;
real minX, maxX, minY, maxY;
#endif
{
ObjPtr valuesArray, rangeArray;
real values[2], range[4];
Bool changed = false;
if (minX >= maxX || minY >= maxY)
{
/* give up! */
ReportError("SetXYControlLimits", "error in XY control range\n");
return false;
}
valuesArray = GetFixedArrayVar("SetXYControlLimits", theControl, VALUE, 1, 2L);
if (!valuesArray)
{
return false;
}
range[0] = minX;
range[1] = maxX;
range[2] = minY;
range[3] = maxY;
rangeArray = NewRealArray (1, 4L);
CArray2Array(rangeArray, range);
SetVar(theControl, RANGE, rangeArray);
/* adjust slider values if they're now out of range */
Array2CArray(values, valuesArray);
if (values[0]<minX || values[0]>maxX || values[1]<minY || values[1]>maxY)
{
changed = true;
values[0] = values[0]<minX ? minX : (values[0]>maxX ? maxX : values[0]);
values[1] = values[1]<minY ? minY : (values[1]>maxY ? maxY : values[1]);
valuesArray = NewRealArray(1, 2L);
CArray2Array(valuesArray, values);
SetVar(theControl, VALUE, valuesArray);
}
ImInvalid(theControl);
if (changed)
{
ChangedValue(theControl);
}
return true;
}
Bool GetXYControlLimits(obj, minX, maxX, minY, maxY)
ObjPtr obj;
real *minX, *minY, *maxX, *maxY;
{
ObjPtr rangeArray;
real range[4];
rangeArray = GetFixedArrayVar("GetXYControlLimits", obj, RANGE, 1, 4L);
if (!rangeArray)
{
return false;
}
Array2CArray(range, rangeArray);
*minX = range[0];
*maxX = range[1];
*minY = range[2];
*maxY = range[3];
return true;
}
#ifdef PROTO
Bool SetXYControlValue(ObjPtr obj, real xvalue, real yvalue)
#else
Bool SetXYControlValue(obj, xvalue, yvalue)
ObjPtr obj;
real xvalue, yvalue;
#endif
/* sets values of 2D control. Non-method version */
{
ObjPtr valuesArray, rangeArray;
real value[2], range[4];
real oldv0, oldv1;
valuesArray = GetFixedArrayVar("SetXYControlValue", obj, VALUE, 1, 2L);
rangeArray = GetFixedArrayVar("SetXYControlValue", obj, RANGE, 1, 4L);
if (!valuesArray || !rangeArray)
{
ReportError("SetXYControlValue", "error in values or range array");
return false;
}
Array2CArray(value, valuesArray);
Array2CArray(range, rangeArray);
oldv0 = value[0];
oldv1 = value[1];
if (xvalue < range[0])
value[0] = range[0];
else if (xvalue > range[1])
value [0] = range[1];
else
value[0] = xvalue;
if (yvalue < range[2])
value[1] = range[2];
else if (yvalue > range[3])
value[1] = range[3];
else
value[1] = yvalue;
valuesArray = NewRealArray(1, 2L);
CArray2Array(valuesArray, value);
SetVar(obj, VALUE, valuesArray);
if (oldv0 != value[0] || oldv1 != value[1])
{
ImInvalid(obj);
ChangedValue(obj);
}
if (logging) LogControl(obj);
return true;
}
Bool GetXYControlValue(obj, xvalue, yvalue)
ObjPtr obj;
real *xvalue, *yvalue;
{
ObjPtr valuesArray;
real value[2];
valuesArray = GetFixedArrayVar("GetXYControlValue", obj, VALUE, 1, 2L);
if (!valuesArray)
{
return false;
}
Array2CArray(value, valuesArray);
*xvalue = value[0];
*yvalue = value[1];
return true;
}
ObjPtr GetXYControlObjValue(obj)
ObjPtr obj;
{
return GetVar(obj, VALUE);
}
void InitXYControls()
{
XYControlClass = NewObject(controlClass, 0);
AddToReferenceList((ThingPtr) XYControlClass);
SetMethod(XYControlClass, DRAW, DrawXYControl);
SetMethod(XYControlClass, PRESS, PressXYControl);
/* These are incorrect until FuncTyp gets redefined
SetMethod(XYControlClass, SETVAL, SetXYControlObjValue);
*/
SetMethod(XYControlClass, GETVAL, GetXYControlObjValue);
SetVar(XYControlClass, TYPESTRING, NewString("control"));
SetVar(XYControlClass, HELPSTRING, NewString(
"This is a two-valued slider. By clicking and dragging the \"thumb\" in \
the control, you can change one or both of the values. You can change only \
one of the values by holding the Shift key down while you click and drag \
the \"thumb\". If you double-click it, the values will snap to the closest \
one of maximum, minimum or middle value of the range for each value."));
}
void KillXYControls()
{
RemoveFromReferenceList(XYControlClass);
}